//
//  userAccount.swift
//  sinaWeibo
//
//  Created by 浅爱 on 16/3/16.
//  Copyright © 2016年 y. All rights reserved.
//

/**
    1.字典转模型
    2.保存数据
    3.对外提供获取数据的方式
*/

import UIKit
import AFNetworking

let userInfoKey = "com.github.account"

class userAccount: NSObject {
    
    // 定义单例userAccount
    static let sharedAccount = userAccount()

    // 用于调用access_token，接口获取授权后的access token。 用户访问接口受限标识
    var access_token: String?
    
    // access_token的生命周期，单位是秒数,用户token过多少秒会过期
    // access_token的生命周期（该参数即将废弃，开发者请使用expires_in）  在接口返回数据中不能删除，接口返回数据接口字段，只能增加不能减少
    var expires_in: NSTimeInterval = 0 {
    
        didSet {
        
            // 计算过期时间
            expires_date = NSDate(timeIntervalSinceNow: expires_in)
            
        }
        
    }
    
    var expires_date: NSDate?
    
    // 当前授权用户的UID
    var uid: String?
    
    // 当前登录用户名称
    var name: String?

    // 用户头像
    var avatar_large: String? {
    
        didSet {
        
            // 耗内存
            headImageUrl = NSURL(string: avatar_large ?? "")
        
        }
    
    }
    
    var headImageUrl: NSURL?
    // 计算型属性 每次执行都会调用，比较耗CPU
    
    // 计算型属性，判断是否登录
    var userLogin: Bool {
    
        
        return access_token != nil
    
    }
    
    // 为了保证单例对象唯一，需要私有化构造函数
    override private init() {
        
        super.init()
        
        // 加载用户信息
        self.loadUserInfo()
        
    }
    
    // 其他不存在的key
    override func setValue(value: AnyObject?, forUndefinedKey key: String) { }
    
    // 测试打印用户详细信息
    override var description: String {
    
        // 只读属性
        let keys = ["access_token", "expires_in", "uid", "name", "avatar_large", "expires_date"]
        
        let accountDict = dictionaryWithValuesForKeys(keys)
        
        
        return accountDict.description
        
    }
    
}

// 账户相关的业务逻辑的扩展
// 保存数据，获取数据
extension userAccount {

    // MARK: 保存用户信息
    func saveUserInfo(dict: [String: AnyObject]) {
     
        // 给当前对象KVC设置值--  未登录->登录
        self.setValuesForKeysWithDictionary(dict)
        
        // 保存当前对象的所有属性
        let userDefaults = NSUserDefaults.standardUserDefaults()
        
        let keys = ["access_token", "expires_in", "uid", "name", "avatar_large", "expires_date"]
        
        let accountDict = self.dictionaryWithValuesForKeys(keys)
        
        userDefaults.setObject(accountDict, forKey: userInfoKey)
        
        // 同步到沙盒
        userDefaults.synchronize()
        
        // 测试
        print(NSHomeDirectory())
        
    }
    
    // 提供对外访问的方式
    // 从磁盘中获取数据， IO操作，效率低 很消耗磁盘
    func loadUserInfo() {
    
        // 从偏好设置中获取字典信息
        guard let dict = NSUserDefaults.standardUserDefaults().objectForKey(userInfoKey) as? [String: AnyObject] else {
        
            
            return
        
        }
        
        // 将字典信息转换成模型数据
        self.setValuesForKeysWithDictionary(dict)
       
        // 如果当前用户token已经过期，就应该将当前用户的信息重置为未登录
        // 如果token不为空  登录   为nil 未登录
        // 过期日期 和 当期日期 比较
        if self.expires_date?.compare(NSDate()) == NSComparisonResult.OrderedDescending {
        
            // 过期日期大于当前日期
            print("token 未过期")
        
        }else {
        
            print("已过期")
            self.access_token = nil
        
        }
       
    }

}


// 账户相关所有的网络请求
extension userAccount {

    // 获取token
    func loadAccessToken(code: String, finished: (isSuccess: Bool) -> ()) {
        
        let urlStr = "https://api.weibo.com/oauth2/access_token"
        
        let parameters = ["client_id": client_id, "client_secret": client_secret, "grant_type": "authorization_code", "code": code, "redirect_uri": redirect_uri]
        
        // 发起网络请求
        let AFN = AFHTTPSessionManager()
        
        // Request failed: unacceptable content-type: text/plain 使用AFN最常见的错误
        AFN.responseSerializer.acceptableContentTypes?.insert("text/plain")
        
        AFN.POST(urlStr, parameters: parameters, progress: nil, success: { (_, result) -> Void in
            
            print(result)
            // 获取token
            guard let dict = result as? [String: AnyObject] else {
                
                // 失败需要执行闭包
                finished(isSuccess: false)
                
                
                return
                
            }
            
            // 用户访问接口的权限的一个时效性的标识
            self.loadUserInfo(dict, finished: finished)
            
            }) { (_, error) -> Void in
                
                // 失败需要执行闭包
                finished(isSuccess: false)
                
                print(error)
                
        }
        
    }
    
    private func loadUserInfo(dict: [String: AnyObject], finished: (isSuccess: Bool) -> ()) {
        
        
        let token = dict["access_token"] as! String
        
        // 获得用户访问接口的权限之后，使用token获取用户信息
        let uid = dict["uid"] as! String
        
        let urlStr = "https://api.weibo.com/2/users/show.json"
        
        let parameters = ["access_token": token, "uid": uid]
        
        let AFN = AFHTTPSessionManager()
        
        AFN.GET(urlStr, parameters: parameters, progress: nil, success: { (_, result) -> Void in
            
            guard var userInfoDict = result as? [String: AnyObject] else {
                
                finished(isSuccess: false)
                
                
                return
                
            }
            
            print(userInfoDict)
            
            // 合并字典
            for (k,v) in dict {
                
                // 合并
                userInfoDict[k] = v
                
            }
            
            // 保存字典到沙盒
            // 沙盒中不能保存空数据
            userAccount.sharedAccount.saveUserInfo(userInfoDict)
            
            // 获取用户信息成功
            finished(isSuccess: true)
            
            }) { (_, error) -> Void in
                
                // 失败需要执行闭包
                finished(isSuccess: false)
                
                print(error)
                
        }
        
    }

}





